package com.project.handler;

import com.project.exception.ControllerException;
import com.project.exception.DaoException;
import com.project.exception.ServiceException;
import com.project.result.ResponseResult;
import com.project.result.ResultCode;
import com.project.entity.vo.ErrorData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @ProjectName:
 * @Package:
 * @ClassName:
 * @Author: zhaolongshi
 * @CreateDate: 2022/3/7 15:53
 */
@SuppressWarnings("all")
@Slf4j
@RestControllerAdvice
public class GlobalHandlerException {
    @ExceptionHandler(Exception.class)
    public ResponseResult<Object> handlerException(Exception e) {
        log.error(e.getMessage());
        return ResponseResult.error();
    }

    /**
     * 针对数据层抛出的异常
     *
     * @param de
     * @return
     */
    @ExceptionHandler(DaoException.class)
    public ResponseResult<Object> handlerException(DaoException de) {
        return ResponseResult.error(de.getResultCode());
    }

    /**
     * 针对业务逻辑层抛出的异常
     *
     * @param se
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    public ResponseResult<Object> handlerException(ServiceException se) {
        return ResponseResult.error(se.getResultCode());
    }

    /**
     * 针对控制层抛出的异常
     *
     * @param ce
     * @return
     */
    @ExceptionHandler(ControllerException.class)
    public ResponseResult<Object> handlerException(ControllerException ce) {
        return ResponseResult.error(ce.getResultCode());
    }

    /**
     * 单参数校验抛出异常
     *
     * @param cve
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseResult<List<String>> handlerConstraintViolationException(ConstraintViolationException cve) {
        //针对普通校验，简单的错误信息
        List<String> errors = new ArrayList<>();
        Set<ConstraintViolation<?>> constraintViolations = cve.getConstraintViolations();
        constraintViolations.forEach(constraintViolation -> {
            //获取注解msg属性上的 值
            errors.add(constraintViolation.getMessage());
        });
        return ResponseResult.error(ResultCode.PARAMS_IS_INVALID, errors);
    }

    @ExceptionHandler(BindException.class)
    public ResponseResult<List<ErrorData>> handlerBindException(BindException be) {
        List<ObjectError> allErrors = be.getAllErrors();
        List<ErrorData> errorDataList = new ArrayList<>();
        allErrors.forEach(error -> {
            errorDataList.add(new ErrorData(error.getObjectName(), error.getDefaultMessage()));
        });
        return ResponseResult.error(ResultCode.PARAMS_IS_INVALID, errorDataList);
    }
}
